package com.ybg.share.core.remoteapi;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ybg.framework.constant.CommonConstant;
import com.ybg.framework.enums.MarketEnum;
import com.ybg.framework.enums.SyncPolicyEnum;
import com.ybg.framework.vo.R;
import com.ybg.share.core.dbapi.entity.ShareStock;
import com.ybg.share.core.dbapi.entity.ShareStockDayK;
import com.ybg.share.core.dbapi.service.ShareStockDayKService;
import com.ybg.share.core.dbapi.service.ShareStockService;
import com.ybg.share.core.remoteapi.datamapper.StockDataMapper;
import com.ybg.share.core.remoteapi.datamapper.StockDayKDataMapper;
import com.ybg.share.core.remoteapi.dto.StockDayKDTO;
import com.ybg.share.core.remoteapi.dto.StockPageQueryDTO;
import com.ybg.share.core.remoteapi.dto.SyncAllDayKDTO;
import com.ybg.share.core.remoteapi.vo.ShareStockVO;
import com.ybg.share.core.remoteapi.vo.StockDayKVO;
import com.ybg.share.core.shareapi.impl.EastMoneyStockInfoApi;
import com.ybg.share.core.shareapi.impl.ShanghaiStockDayKApi;
import com.ybg.share.core.shareapi.impl.ShenzhenStockDayKApi;
import com.ybg.share.schedule.FixDataJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.function.Function;
@Slf4j
@Service(version = "${dubbo.provider.version}")
public class StockRemoteApiImpl implements StockRemoteApi {
    @Autowired
    private ShareStockService shareStockService;
    @Autowired
    private ShareStockDayKService shareStockDayKService;
    @Autowired
    private EastMoneyStockInfoApi eastMoneyStockInfoApi;
    @Autowired
    private FixDataJob fixDataJob;
    @Autowired
    private ShanghaiStockDayKApi shanghaiStockDayKApi;
    @Autowired
    private ShenzhenStockDayKApi shenzhenStockDayKApi;

    @Override
    public List<ShareStockVO> queryShare(String input) {
        QueryWrapper<ShareStock> wrapper = new QueryWrapper<>();
        wrapper.eq(ShareStock.STATUS, CommonConstant.STATUS_NORMAL);
        wrapper.and(new Function<QueryWrapper<ShareStock>, QueryWrapper<ShareStock>>() {
            @Override
            public QueryWrapper<ShareStock> apply(QueryWrapper<ShareStock> shareStockQueryWrapper) {
                shareStockQueryWrapper.like(ShareStock.CODE, input).or();
                shareStockQueryWrapper.like(ShareStock.SPELL, input).or();
                shareStockQueryWrapper.like(ShareStock.NAME, input);
                shareStockQueryWrapper.last(" LIMIT 5");
                return shareStockQueryWrapper;
            }
        });
        List<ShareStock> list = shareStockService.list(wrapper);
        return StockDataMapper.INSTANCES.toVOList(list);
    }

    @Override
    public ShareStockVO getByCode(String code) {
        ShareStock shareStock = shareStockService.getByCode(code);
        return StockDataMapper.INSTANCES.toVO(shareStock);
    }

    @Override
    public ShareStockVO getById(Long id) {
        ShareStock shareStock = shareStockService.getById(id);
        return StockDataMapper.INSTANCES.toVO(shareStock);
    }

    @Override
    public ShareStockVO getByPinyin(String pinyin) {

        QueryWrapper<ShareStock> wrapper = new QueryWrapper<>();
        wrapper.eq(ShareStock.STATUS, CommonConstant.STATUS_NORMAL);
        wrapper.eq(ShareStock.SPELL, pinyin);
        ShareStock shareStock = shareStockService.getOne(wrapper);
        return StockDataMapper.INSTANCES.toVO(shareStock);
    }

    @Override
    public R syncAllStock() {
        //todo 加入锁
        eastMoneyStockInfoApi.execute();
        return R.success();
    }

    @Override
    public R updateAllStockInfo() {
        //todo 加入锁
        fixDataJob.fixStockState();
        return R.success();
    }



    @Override
    public Page<ShareStockVO> page(StockPageQueryDTO dto) {
       return  shareStockService.pageStock( dto);
    }

    @Override
    public List<StockDayKVO> getDayK(Long stockId, String startDate, String endDate) {
        QueryWrapper<ShareStockDayK> wrapper = new QueryWrapper<>();
        wrapper.eq(ShareStockDayK.STOCK_ID, stockId);
        wrapper.ge(StrUtil.isNotBlank(startDate), ShareStockDayK.REF_DATE, startDate);
        wrapper.le(StrUtil.isNotBlank(endDate), ShareStockDayK.REF_DATE, endDate);
        List<ShareStockDayK> list = shareStockDayKService.list(wrapper);
        return StockDayKDataMapper.INSTANCE.toVOList(list);
    }

    @Override
    public R syncOneDayK(Long stockId) {
        QueryWrapper<ShareStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ShareStock.STATUS, 1);
        ShareStock shareStock = shareStockService.getById(queryWrapper);
        if (shareStock == null) {
            return R.fail("股票为空");
        }
        if (shareStock.getMarket().equals(MarketEnum.sh.getCode())) {
            shanghaiStockDayKApi.execute(shareStock, SyncPolicyEnum.all_ignore);
        }
        if (shareStock.getMarket().equals(MarketEnum.sz.getCode())) {

            shenzhenStockDayKApi.execute(shareStock, SyncPolicyEnum.all_ignore);
        }
        return R.success();
    }

    @Override
    public R syncAllDayK(SyncAllDayKDTO dto) {
        //todo 加入锁
        QueryWrapper<ShareStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ShareStock.STATUS, 1);
        queryWrapper.eq(StrUtil.isNotBlank(dto.getMarket()), ShareStock.MARKET, dto.getMarket());
        queryWrapper.ge(dto.getMinStockId() != null, ShareStock.ID, dto.getMinStockId());
        queryWrapper.ge(dto.getMaxStockId() != null, ShareStock.ID, dto.getMaxStockId());
        queryWrapper.eq(dto.getStockId() != null, ShareStock.ID, dto.getStockId());
        List<ShareStock> list = shareStockService.list(queryWrapper);
        for (ShareStock shareStock : list) {
            try {
                //防止过快 撑爆内存和cpu
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (shareStock.getMarket().equals(MarketEnum.sh.getCode())) {
                shanghaiStockDayKApi.execute(shareStock, SyncPolicyEnum.all_ignore);
            }
            if (shareStock.getMarket().equals(MarketEnum.sz.getCode())) {

                shenzhenStockDayKApi.execute(shareStock, SyncPolicyEnum.all_ignore);
            }
            //todo  释放锁
        }
        return R.success();
    }

    @Override
    public R<?> banStock(Long stockId) {
        ShareStock stock = shareStockService.getById(stockId);
        if(stock==null){
            return R.fail("数据为空");
        }
        ShareStock updateWrapper= new ShareStock();
        updateWrapper.setId(stockId);
        updateWrapper.setStatus(!stock.getStatus());
        shareStockService.updateById(updateWrapper);
        return R.success();
    }

    @Override
    public Page<StockDayKVO> pageDayK(StockDayKDTO dto) {
        if (StrUtil.isNotBlank(dto.getName())){
            QueryWrapper<ShareStock> queryWrapper = new QueryWrapper<>();
            queryWrapper.like(ShareStock.NAME,dto.getName());
            List<ShareStock> list = shareStockService.list(queryWrapper);
            if (list.size() == 0){
                return new Page<>();
            }
            if (list.size() > 1){
                StringBuilder stockIds = new StringBuilder();
                for (ShareStock shareStock : list) {
                    stockIds.append(",").append(shareStock.getId());
                }
                dto.setStockIds(stockIds.substring(1));
            }
            if (list.size() == 1){
                dto.setStockId(list.get(0).getId());
            }
        }
        return shareStockDayKService.page(dto);
    }
}
